#pragma once
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include "TempleteFea.h"
#include "utilfun.h"
#include "utilio.h"
#include <iostream>
#include "binstore.h"

class grid_node
{
public:
	int			  tag_id;
	vector<span_feature*> income_edges;
	vector<span_feature*> outcome_edges;

	grid_node() {
		tag_id=0;
	}
};

class crfHolder
{
public:
	double	_obj;
	double*	_lambda;
	double*	_gradient;
	
	int					_tag_size;
	vector<int*>		_tagid2gridid;
	vector<grid_node*>	_node_grid;
	vector<double*>		_grid_alpha;
	vector<double*>		_grid_beta;
	memPool<double>		_grid_alphabeta_pool;
	memPool<grid_node>	_grid_memPool;
	memPool<int>		_tagid_memPool;

	vector<int*>		_grid_backtrack;
	memPool<int>		_backtrack_memPool;


	double*	_alpha;
	double* _beta;
	memPool<double>	    _double_pool;
	int					_tag_sentence_begin;

	void build_lattice(sentence& sen);

	void calculate_alpha(sentence& sen);

	void calculate_beta(sentence& sen);

	double calculate_Z(sentence& sen);

	double calculate_cost(sentence& sen);
 
	void calculate_gradient(sentence& sen,double& z_all);

	double decode(sentence& sen,vector<int>& predict_label);

	double process_sen(sentence& sen);

	double process_decode(sentence& sen,vector<int>& predict_label);
};
//////////////////////////////////////////////////////////////////////////

class crfTrainImp
{
public:
	crfTrainImp();
	~crfTrainImp() { if(_gradient) delete[]( _gradient);if(_lambda) delete[](_lambda); }


	void Train(char *fea_file,char* lambda_file,vector<string> trainfiles,int save_step=2,int save_startid=0,bool bcheck=false);

	double *_lambda;
	double *_gradient;
	int		_feature_num_all;
	int _depth;
	int _prior;
	int _sen_num;

	double _sigma;
	double _eta;
	memPool<char> pool_work_space;
	freelist<char> _temp_space;
	crfHolder	   _foMst;
	memPool<char> temPool;
};